/*
 * Class: DataMigrationView
 * Created by: Mary Joy Pascual
 * Date Created: 06/17/2014
 * Company: Netsuite
*/
package com.netsuite.view;

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;

import javax.swing.DropMode;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.border.TitledBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.DefaultTableModel;

import com.netsuite.constants.Constants;
import com.netsuite.controller.CustomerRefundController;
import com.netsuite.controller.StateController;
import com.netsuite.helper.ErrorHelper;
import com.netsuite.helper.FileReaderCSVHelper;
import com.netsuite.helper.FileReaderXMLHelper;
import com.netsuite.helper.MessageViewHelper;
import com.netsuite.helper.TransferHelper;
import com.netsuite.logger.LoggerImp;
import com.netsuite.migration.CSV;

import javax.swing.JLabel;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;

import java.awt.Color;
import java.awt.Font;

public class DataMigrationView extends JFrame{
	
	private static String CLASS_NAME = DataMigrationView.class.getName();

	private static final long serialVersionUID = 1L;
	private CSV csv;
	private StateController stateController;
	private CustomerRefundController customerRefundController;
	private JFrame frmDataMigration;
	private JTextField fileName;
	private JTextField dirName;
	private JButton btnProcess;
	private JButton button;
	private JPanel titlePanel;
	private JPanel titlePanel2;
	private DefaultTableModel model;
	private JScrollPane scrollPane;
	private JTable table_1;
	private JButton btnMap;
	private JFrame loader;
	private JCheckBox mapCheckBox;
	private JComboBox<String> comboBox;

	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					DataMigrationView window = new DataMigrationView();
					window.frmDataMigration.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	public DataMigrationView() {
		initialize();
	}

	private void initialize() {
		
		LoggerImp.startLog(CLASS_NAME, "initialize()");

		frmDataMigration = new JFrame();
		frmDataMigration.setTitle("Data Migration");
		frmDataMigration.setBounds(100, 100, 448, 508);
		frmDataMigration.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frmDataMigration.getContentPane().setLayout(null);
		frmDataMigration.setLocationRelativeTo(null);
		
		try {
			stateController = new StateController();
			customerRefundController = new CustomerRefundController();
		} catch (ErrorHelper e) {
			MessageViewHelper.displayErrorView(e);
		}

		fileUploader();
		titleMapper();
		
		LoggerImp.endLog(CLASS_NAME, "initialize()");
	}

	public void fileUploader() {
		
		LoggerImp.startLog(CLASS_NAME, "fileUploader()");
		
		JPanel panel = new JPanel();
		panel.setBorder(new TitledBorder(null, "Scan & Upload CSV", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		panel.setBounds(41, 26, 347, 102);
		frmDataMigration.getContentPane().add(panel);
		panel.setLayout(null);

		fileName = new JTextField();
		fileName.setBounds(22, 63, 243, 27);
		fileName.setEditable(false);
		fileName.getDocument().addDocumentListener(new DocumentListener() {
			@Override
			public void changedUpdate(DocumentEvent arg0) {
				validateBtn();
			}
			@Override
			public void insertUpdate(DocumentEvent arg0) {
				validateBtn();
			}

			@Override
			public void removeUpdate(DocumentEvent arg0) {
				validateBtn();
			} 
		});

		panel.add(fileName);
		fileName.setColumns(10);
		
		dirName = new JTextField();
		dirName.setBounds(22, 17, 300, 11);
		dirName.setVisible(false);
		panel.add(dirName);
		dirName.setColumns(10);
		
		button = new JButton("...");
		button.setBounds(277, 64, 45, 25);
		button.addActionListener(new OpenSaveL());
		button.setFocusable(false);
		panel.add(button);
		
		comboBox = new JComboBox <String>();
		comboBox.setFont(new Font("Tahoma", Font.PLAIN, 12));
		comboBox.setBounds(22, 28, 300, 27);
		comboBox.setFocusable(false);
		comboBox.addItem(Constants.STATE);
		comboBox.addItem(Constants.CUS_REF);
		panel.add(comboBox);
		
		btnProcess = new JButton("Load");
		btnProcess.setEnabled(false);
		btnProcess.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
		    	initLoadingPanel();
				SwingWorker <CSV, CSV> worker = new SwingWorker<CSV, CSV>() {
					
				    @Override
				    protected CSV doInBackground() throws Exception {
				        return FileReaderCSVHelper.fileReader(dirName.getText(), fileName.getText());
				    }

				    @Override
				    protected void done() {
				    	loader.dispose();
				        try {
				            csv = get();
				            String selectedField = ((String)comboBox.getSelectedItem());
				            List <String> fieldNames = null;
					    	if(selectedField.equals(Constants.STATE)){
					    		fieldNames = stateController.getFieldNames();
					    	} else if (selectedField.equals(Constants.CUS_REF)) {
					    		fieldNames = customerRefundController.getFieldNames();
					    	}
				            generateTableList(csv.getCsvTitle(), fieldNames);
				        } catch (ExecutionException e) {
				        	MessageViewHelper.displayErrorView(e);
				        } catch (Exception e){
				        	MessageViewHelper.displayErrorView(e);
				        }
				       
				    }

				};
				worker.execute();
			}
		});
		btnProcess.setBounds(291, 137, 97, 25);
		frmDataMigration.getContentPane().add(btnProcess);

		LoggerImp.endLog(CLASS_NAME, "fileUploader()");
		
	}
	
	public void titleMapper(){
		
		LoggerImp.startLog(CLASS_NAME, "titleMapper()");
		
		titlePanel = new JPanel();
		titlePanel.setBorder(new TitledBorder(null, "Fields Mapper", TitledBorder.LEADING, TitledBorder.TOP, null, null));
		titlePanel.setBounds(41, 176, 347, 239);
		frmDataMigration.getContentPane().add(titlePanel);
		titlePanel.setLayout(null);
		
		titlePanel2 = new JPanel();
		titlePanel2.setBounds(12, 24, 323, 158);
		
		model = new DefaultTableModel();
		model.addColumn("CSV");
		model.addColumn("Netsuite");
		
		table_1 = new JTable(model);
		table_1.setPreferredScrollableViewportSize(new Dimension(300, 120));
		table_1.setDragEnabled(true);  
		table_1.setDropMode(DropMode.USE_SELECTION);  
		table_1.setTransferHandler(new TransferHelper()); 
		table_1.setRowSelectionAllowed(false);
		table_1.setCellSelectionEnabled(true);
	
		scrollPane = new JScrollPane(table_1);
		scrollPane.setBounds(12, 13, 705, 361);
		titlePanel2.add(scrollPane);
		titlePanel.add(titlePanel2);
		
		mapCheckBox = new JCheckBox("Map fields using MapperConfig.xml");
		mapCheckBox.setForeground(Color.BLACK);
		mapCheckBox.setBounds(56, 191, 238, 25);
		titlePanel.add(mapCheckBox);
		
		btnMap = new JButton("Map");
		btnMap.setEnabled(false);
		btnMap.setBounds(291, 428, 97, 25);
		btnMap.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				if(btnMap.isEnabled()){
					int dialogResult = JOptionPane.showConfirmDialog (null, "Are you done mapping the fields in the MapperConfig.xml?");
					if(dialogResult == JOptionPane.YES_OPTION){
						initLoadingPanel();
						SwingWorker <String, String> worker = new SwingWorker<String, String>() {
							
						    @Override
						    protected String doInBackground() throws Exception {
						    	Map<String, String> titleMap = null;
						    	if(mapCheckBox.isSelected()){
						    		titleMap = FileReaderXMLHelper.stateMapperReader();
						    	} else {
						    		titleMap = iterateDataTableToMap();
						    	}
						    	
						    	String message = "";
						    	String selectedField = ((String)comboBox.getSelectedItem());
						    	if(selectedField.equals(Constants.STATE)){
						    		message = stateController.upsertRecord(titleMap, csv);
						    	} else if (selectedField.equals(Constants.CUS_REF)){
						    		message = customerRefundController.upsertRecord(titleMap, csv);
						    	} 
						        return message;
						    }

						    @Override
						    protected void done() {
						    	loader.dispose();
						        try {
						            MessageViewHelper.displaySuccessView(get());
									resetFields();
						        } catch (ExecutionException e ) {
						        	MessageViewHelper.displayErrorView(e);
						        } catch (Exception e){
						        	MessageViewHelper.displayErrorView(e);
						        }
						       
						    }

						};
						worker.execute();
					
					} 
				}
			}
		});
		frmDataMigration.getContentPane().add(btnMap);
		
		LoggerImp.endLog(CLASS_NAME, "titleMapper()");
		
	}
	
	private void generateTableList(List<String> csvList, List<String> netSuiteList){
		
		LoggerImp.startLog(CLASS_NAME, "generateTableList()");
		
		model.setRowCount(0);
		int size = 0;
		if(csvList.size() > netSuiteList.size()){
			size = csvList.size();
		} else {
			size = netSuiteList.size();
		}
		for (int i=0; i<size; i++){
			String csv = "";
			String netsuite = "";
			if(i < csvList.size()){
				csv = csvList.get(i);
			}
			if(i < netSuiteList.size()){
				netsuite = netSuiteList.get(i);
			}
			model.addRow(new Object[]{csv, netsuite});
		}
		if(model.getRowCount() != 0){
			btnMap.setEnabled(true);
		}
		
		LoggerImp.endLog(CLASS_NAME, "generateTableList()");
		
	}
	
	private void validateFileName(String file){
		
		LoggerImp.startLog(CLASS_NAME, "validateFileName()");
		
		int i = file.lastIndexOf('.');
		if (i > 0) {
		    String extension = file.substring(i+1);
		    if(!extension.equalsIgnoreCase("csv")){
		    	MessageViewHelper.displayValidationError("Invalid File Extension. Only CSV files are allowed.");
		    	fileName.setText("");
				dirName.setText("");
		    }
		}
		
		LoggerImp.endLog(CLASS_NAME, "validateFileName()");
		
	}
	
	private void validateBtn(){
		
		LoggerImp.startLog(CLASS_NAME, "validateBtn()");
		
		if(!fileName.getText().equalsIgnoreCase("")){
			btnProcess.setEnabled(true);
		}else {
			btnProcess.setEnabled(false);
		}
		
		LoggerImp.endLog(CLASS_NAME, "validateBtn()");
		
	}
	
	private Map<String, String> iterateDataTableToMap(){
		Map<String, String> map = new HashMap<String, String>();
		DefaultTableModel dtm = (DefaultTableModel) table_1.getModel();
		for(int i = 0; i < dtm.getRowCount(); i++){
			String netsuite = (String)dtm.getValueAt(i, 1);
			String csv = (String)dtm.getValueAt(i, 0);
			if(!netsuite.equalsIgnoreCase("") && !csv.equalsIgnoreCase("")){
				map.put(netsuite, csv);
			}
		}
		return map;
	}

	class OpenSaveL implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			JFileChooser c = new JFileChooser();
			int rVal = c.showOpenDialog(DataMigrationView.this);
			if (rVal == JFileChooser.APPROVE_OPTION) {
				fileName.setText(c.getSelectedFile().getName());
				dirName.setText(c.getCurrentDirectory().toString());
				validateFileName(fileName.getText());
			}
			if (rVal == JFileChooser.CANCEL_OPTION) {
				fileName.setText("");
				dirName.setText("");
			}
		}
	}
	
	public void resetFields (){
		
		LoggerImp.startLog(CLASS_NAME, "resetFields()");
		
		model.setRowCount(0);
		fileName.setText("");
		dirName.setText("");
		btnProcess.setEnabled(false);
		btnMap.setEnabled(false);
		button.setEnabled(true);
		
		LoggerImp.endLog(CLASS_NAME, "resetFields()");
		
	}
	
	
	public void disableButtons (){
		
		LoggerImp.startLog(CLASS_NAME, "resetFields()");
		
		model.setRowCount(0);
		btnProcess.setEnabled(false);
		btnMap.setEnabled(false);
		button.setEnabled(false);
		
		LoggerImp.endLog(CLASS_NAME, "resetFields()");
		
	}
	
	public void initLoadingPanel(){
		 SwingUtilities.invokeLater(new Runnable() {
             @Override
             public void run() {
                 loader = new JFrame("Loading....");
                 ImageIcon img = new ImageIcon("loader.gif");
                 loader.getContentPane().add(new JLabel(" Loading...", img, JLabel.CENTER)); 
                 loader.setResizable(false);
                 loader.setAlwaysOnTop(true);
                 loader.setDefaultCloseOperation( JFrame.DO_NOTHING_ON_CLOSE );
                 loader.pack();
                 loader.setSize(300, 100);
                 loader.setVisible(true);
                 loader.setLocationRelativeTo(null);
             }
         });
	}
}
